using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._RasterAnalysisTools._AnalyzePatterns
{
    /// <summary>
    /// <para>Interpolate Points</para>
    /// <para>Predicts values at new locations based on measurements from a collection of points. The tool takes point data with values at each point and returns a raster of predicted values.</para>
    /// <para>根据点集合的测量值预测新位置的值。该工具获取包含每个点值的点数据，并返回预测值的栅格。</para>
    /// </summary>    
    [DisplayName("Interpolate Points")]
    public class InterpolatePoints : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public InterpolatePoints()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_inputPointFeatures">
        /// <para>Input Point Features</para>
        /// <para>The input point features you want to interpolate.</para>
        /// <para>要插值的输入点要素。</para>
        /// </param>
        /// <param name="_interpolateField">
        /// <para>Interpolate Field</para>
        /// <para>The field containing the data values you want to interpolate. The field must be numeric.</para>
        /// <para>包含要插值的数据值的字段。该字段必须为数字。</para>
        /// </param>
        /// <param name="_outputName">
        /// <para>Output Name</para>
        /// <para><xdoc>
        ///   <para>The name of the output raster service.</para>
        ///   <para>The default name is based on the tool name and the input layer name. If the layer name already exists, you will be prompted to provide another name.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>输出栅格服务的名称。</para>
        ///   <para>默认名称基于工具名称和输入图层名称。如果图层名称已存在，系统将提示您提供其他名称。</para>
        /// </xdoc></para>
        /// </param>
        public InterpolatePoints(object _inputPointFeatures, object _interpolateField, object _outputName)
        {
            this._inputPointFeatures = _inputPointFeatures;
            this._interpolateField = _interpolateField;
            this._outputName = _outputName;
        }
        public override string ToolboxName => "Raster Analysis Tools";

        public override string ToolName => "Interpolate Points";

        public override string CallName => "ra.InterpolatePoints";

        public override List<string> AcceptEnvironments => ["cellSize", "extent", "mask", "outputCoordinateSystem", "snapRaster"];

        public override object[] ParameterInfo => [_inputPointFeatures, _interpolateField, _outputName, _optimizeFor.GetGPValue(), _transformData.GetGPValue(), _sizeOfLocalModels, _numberOfNeighbors, _outputCellSize, _outputPredictionError.GetGPValue(), _outputRaster, _outputErrorRaster];

        /// <summary>
        /// <para>Input Point Features</para>
        /// <para>The input point features you want to interpolate.</para>
        /// <para>要插值的输入点要素。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Point Features")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _inputPointFeatures { get; set; }


        /// <summary>
        /// <para>Interpolate Field</para>
        /// <para>The field containing the data values you want to interpolate. The field must be numeric.</para>
        /// <para>包含要插值的数据值的字段。该字段必须为数字。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Interpolate Field")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _interpolateField { get; set; }


        /// <summary>
        /// <para>Output Name</para>
        /// <para><xdoc>
        ///   <para>The name of the output raster service.</para>
        ///   <para>The default name is based on the tool name and the input layer name. If the layer name already exists, you will be prompted to provide another name.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>输出栅格服务的名称。</para>
        ///   <para>默认名称基于工具名称和输入图层名称。如果图层名称已存在，系统将提示您提供其他名称。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Name")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _outputName { get; set; }


        /// <summary>
        /// <para>Optimize For</para>
        /// <para><xdoc>
        ///   <para>Choose your preference for speed versus accuracy. More accurate predictions will take longer to calculate.</para>
        ///   <bulletList>
        ///     <bullet_item>Speed—The operation is optimized for speed.</bullet_item><para/>
        ///     <bullet_item>Balance—A balance between speed and accuracy. This is the default.</bullet_item><para/>
        ///     <bullet_item>Accuracy—The operation is optimized for accuracy.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>选择您对速度与准确性的偏好。更准确的预测将需要更长的时间来计算。</para>
        ///   <bulletList>
        ///     <bullet_item>速度 - 操作针对速度进行了优化。</bullet_item><para/>
        ///     <bullet_item>平衡 - 速度和准确性之间的平衡。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>精度 - 针对精度对操作进行了优化。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Optimize For")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _optimizeFor_value _optimizeFor { get; set; } = _optimizeFor_value._BALANCE;

        public enum _optimizeFor_value
        {
            /// <summary>
            /// <para>Speed</para>
            /// <para>Speed—The operation is optimized for speed.</para>
            /// <para>速度 - 操作针对速度进行了优化。</para>
            /// </summary>
            [Description("Speed")]
            [GPEnumValue("SPEED")]
            _SPEED,

            /// <summary>
            /// <para>Balance</para>
            /// <para>Balance—A balance between speed and accuracy. This is the default.</para>
            /// <para>平衡 - 速度和准确性之间的平衡。这是默认设置。</para>
            /// </summary>
            [Description("Balance")]
            [GPEnumValue("BALANCE")]
            _BALANCE,

            /// <summary>
            /// <para>Accuracy</para>
            /// <para>Accuracy—The operation is optimized for accuracy.</para>
            /// <para>精度 - 针对精度对操作进行了优化。</para>
            /// </summary>
            [Description("Accuracy")]
            [GPEnumValue("ACCURACY")]
            _ACCURACY,

        }

        /// <summary>
        /// <para>Transform Data to Normal Distribution</para>
        /// <para><xdoc>
        ///   <para>Choose whether to transform your data to a normal distribution before performing analysis. If your data values do not appear to be normally distributed (bell-shaped), it is recommended to perform a transformation.</para>
        ///   <bulletList>
        ///     <bullet_item>Checked—A transformation to the normal distribution is applied.</bullet_item><para/>
        ///     <bullet_item>Unchecked—No transformation is applied. This is the default.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>在执行分析之前，选择是否将数据转换为正态分布。如果数据值看起来不是正态分布（钟形），则建议执行转换。</para>
        ///   <bulletList>
        ///     <bullet_item>选中 - 应用正态分布的变换。</bullet_item><para/>
        ///     <bullet_item>未选中 - 不应用任何变换。这是默认设置。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Transform Data to Normal Distribution")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _transformData_value _transformData { get; set; } = _transformData_value._false;

        public enum _transformData_value
        {
            /// <summary>
            /// <para>TRANSFORM</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("TRANSFORM")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>NO_TRANSFORM</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NO_TRANSFORM")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Size of Local Models</para>
        /// <para>Choose the number of points in each of the local models. A larger value will make the interpolation more global and stable, but small-scale effects may be missed. Smaller values will make the interpolation more local, so small-scale effects are more likely to be captured, but the interpolation may be unstable.</para>
        /// <para>选择每个局部模型中的点数。较大的值将使插值更加全局和稳定，但可能会遗漏小比例效应。较小的值将使插值更加局部，因此更有可能捕获小比例效果，但插值可能不稳定。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Size of Local Models")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long? _sizeOfLocalModels { get; set; } = null;


        /// <summary>
        /// <para>Number of Neighbors</para>
        /// <para>The number of neighbors to use when calculating the prediction at a particular cell.</para>
        /// <para>计算特定像元的预测时要使用的邻居数。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Number of Neighbors")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long? _numberOfNeighbors { get; set; } = null;


        /// <summary>
        /// <para>Output Cell Size</para>
        /// <para><xdoc>
        ///   <para>Set the cell size and units of the output raster. If a prediction error raster is created, it will also use this cell size.</para>
        ///   <para>The units can be Kilometers, Meters, Miles, or Feet.</para>
        ///   <para>The default units are Meters.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>设置输出栅格的像元大小和单位。如果创建了预测误差栅格，则该栅格也将使用此像元大小。</para>
        ///   <para>单位可以是公里、米、英里或英尺。</para>
        ///   <para>默认单位为米。</para>
        /// </xdoc></para>
        /// <para>单位： Meters | Kilometers | Feet | Miles </para>
        /// </summary>
        [DisplayName("Output Cell Size")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public string? _outputCellSize { get; set; } = null;


        /// <summary>
        /// <para>Output Prediction Error</para>
        /// <para><xdoc>
        ///   <para>Choose whether to output a raster of standard errors of the interpolated predictions.</para>
        ///   <para>Standard errors are useful because they provide information about the reliability of the predicted values. A simple rule of thumb is that the true value will fall within two standard errors of the predicted value 95 percent of the time. For example, suppose a new location gets a predicted value of 50 with a standard error of 5. This means that this task's best guess is that the true value at that location is 50, but it reasonably could be as low as 40 or as high as 60. To calculate this range of reasonable values, multiply the standard error by 2, add this value to the predicted value to get the upper end of the range, and subtract it from the predicted value to get the lower end of the range.</para>
        ///   <para>If a raster of standard errors for the interpolated predictions is requested, it will have the same name as the Result layer name but with Errors appended.</para>
        ///   <bulletList>
        ///     <bullet_item>Unchecked—No output prediction error is generated. This is the default.</bullet_item><para/>
        ///     <bullet_item>Checked—An output prediction error is generated.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>选择是否输出插值预测的标准误差栅格。</para>
        ///   <para>标准误差很有用，因为它们提供了有关预测值可靠性的信息。一个简单的经验法则是，在95%的时间内，真实值将落在预测值的两个标准误差内。例如，假设新位置的预测值为 50，标准误差为 5。这意味着此任务的最佳猜测是该位置的真实值为 50，但合理地可能低至 40 或高至 60。要计算此合理值范围，请将标准误差乘以 2，将此值与预测值相加得到范围的上限，然后从预测值中减去它得到范围的下限。</para>
        ///   <para>如果请求插值预测的标准误差栅格，则该栅格的名称将与结果图层名称相同，但附加了错误。</para>
        ///   <bulletList>
        ///     <bullet_item>未选中 - 不生成输出预测误差。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>选中 - 生成输出预测误差。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Prediction Error")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _outputPredictionError_value _outputPredictionError { get; set; } = _outputPredictionError_value._false;

        public enum _outputPredictionError_value
        {
            /// <summary>
            /// <para>OUTPUT_ERROR</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("OUTPUT_ERROR")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>NO_OUTPUT_ERROR</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NO_OUTPUT_ERROR")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Output Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputRaster { get; set; }


        /// <summary>
        /// <para>Output Error Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Error Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputErrorRaster { get; set; }


        public InterpolatePoints SetEnv(object cellSize = null, object extent = null, object mask = null, object outputCoordinateSystem = null, object snapRaster = null)
        {
            base.SetEnv(cellSize: cellSize, extent: extent, mask: mask, outputCoordinateSystem: outputCoordinateSystem, snapRaster: snapRaster);
            return this;
        }

    }

}